﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using System.CodeDom;

namespace Green.AgileMapper
{
    public abstract class ObjectMapperBase : IObjectMapper
    {

        protected static Dictionary<MapperKey, IMappingRule[]> mappingOperations = new Dictionary<MapperKey, IMappingRule[]>();
        private static readonly object operationsLock = new object();
        public IAgileMapperTemplateStrategy AgileMapperTemplateStrategy
        {
            get;
            protected set;
        }

        public IMappingConfigurator MappingConfigurator
        {
            get;
            private set;
        }

        public ObjectMapperBase(IMappingConfigurator mappingConfigurator)
        {
            this.MappingConfigurator = mappingConfigurator;
        }

        protected virtual IMappingRule[] GetMappingOperations(Type fromType, Type toType, object fromObj)
        {
            if (MappingConfigurator.IsNeedCache)
            {
                var mapperKey = new MapperKey(fromType, toType, MappingConfigurator.GetConfigurationName());
                if (!mappingOperations.ContainsKey(mapperKey))
                {
                    lock (operationsLock)
                    {
                        if (!mappingOperations.ContainsKey(mapperKey))
                        {
                            mappingOperations.Add(mapperKey, MappingConfigurator.GetMappingRule(fromObj));
                        }
                    }

                }
                return mappingOperations[mapperKey];
            }

            return MappingConfigurator.GetMappingRule(fromObj);
        }
        #region IObjectMapper 成员

        public abstract object Warp(Type FromType, object to);

        public abstract void Warp(Type toType, object from, object to);

        public abstract void Warp(object from, object to);


        public abstract string CodeGenerator(Type FromType, Type toType, object fromObj);

        public abstract string CodeGenerator(Type FromType, Type toType);

        public abstract void ApplyAgileMapperTemplateStrategy(IAgileMapperTemplateStrategy strategy);       

        #endregion
    }
}
